package twitter.RequestHandler;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.w3c.dom.Document;

import twitter.Database.TwitterMaintainer;
import twitter.RequestParser.BackendRequestParser;
import twitter.RequestParser.FrontendRequestParser;
import twitter.TwitterLibrary.Utility;

/*****************************************************************
 * abstrct class for handling httprequest.it will get the http request and pass 
 * the request to a RequestParser to parse the request
 * @author fang
 *
 */

public  class HTTPRequestHandler implements Runnable{

	private String end;
	private Socket clientSocket;
	protected ReentrantReadWriteLock rwl;
	private HTTPRequestHandler handler;
	private TwitterMaintainer twitterMaintainer=null;
	private HashMap<String, Document> versionCache;
	private HashMap<String, Integer> tagCache;
	protected Utility utility;
	public HTTPRequestHandler (ReentrantReadWriteLock rwl,Utility utility)
	{
		//this.end=end;
		this.rwl=rwl;
		this.utility=utility;
		
		
	}
	/*********************************************
	 * to get the requested Socket Object 
	 * @param clientSocket fron clientSocket we can get the request
	 */
	public void setTask(Socket clientSocket)
	{
		this.clientSocket=clientSocket;
		
		
	}
	
	public void setTwitterMaintainer(TwitterMaintainer twitterMaintainer)
	{
		//parser=new BackendRequestParser(twitterMaintainer);
		this.twitterMaintainer=twitterMaintainer;
	}
	
	public void setCache(HashMap<String, Document> versionCache,
			HashMap<String, Integer> tagCache) {
		this.versionCache=versionCache;
		this.tagCache=tagCache;

		//frontendParser=new FrontendRequestParser(end,rwl);
		//frontendParser.setCache(versionCache, tagCache);
	}
	/************************************************
	 * process the  request
	 * @param httpInput: the query string
	 * @param httpOutput:the output
	 */
	public   void parseHttpRequest(String httpInput, PrintWriter httpOutput){}
	
	/*****************************************************
	 * get request from the clientsocket
	 * and pass the request to parseHttpRequest method to parse this request
	 */
	public void run()
	{
		
		PrintWriter out;
		try {
			out = new PrintWriter(clientSocket.getOutputStream(), true);
			BufferedReader in = new BufferedReader(
					new InputStreamReader(clientSocket.getInputStream()));

			String fromClient = "";
			StringBuilder sb = new StringBuilder();
			while ((fromClient = in.readLine()) != null) {
				sb.append(fromClient);
				System.out.println("fromClient "+fromClient);
			//	if (fromClient.trim().toLowerCase().startsWith(this.end)) {
					
				//	this.parseHttpRequest(sb.toString(),out);

					//out.close();
					//break;
				//}
				/***************************************************************
				 * 
				 */
				if (fromClient.trim().toLowerCase().startsWith("end")) {
				
					handler=new PrimaryRequestHandler(rwl,this.utility);
					
					
					handler.setTwitterMaintainer(twitterMaintainer);
				
					handler.parseHttpRequest(sb.toString(), out);
					out.close();
					break;
					
				}
				else if(fromClient.trim().toLowerCase().startsWith("backend"))
				{
                    handler=new BackendHttpRequestHandler(rwl,this.utility);
					
					
					handler.setTwitterMaintainer(twitterMaintainer);
				
					handler.parseHttpRequest(sb.toString(), out);
					out.close();
					break;
				}
				else if(fromClient.trim().toLowerCase().startsWith("connection"))
				{
				
					handler=new FrontendHttpRequestHandler(rwl,this.utility);
					handler.setCache(versionCache, tagCache);
				
					handler.parseHttpRequest(sb.toString(), out);
					out.close();
					break;
					
				}
				else if(fromClient.trim().toLowerCase().startsWith("notification"))
				{
					System.out.println("cccc");
					handler=new NoticeResponseHandler(rwl,utility);
				
					handler.parseHttpRequest(sb.toString(), out);
					out.close();
					break;
					
				}
				else if(fromClient.trim().toLowerCase().startsWith("registration"))
				{
					
					handler=new ServerRegistrationHandler(rwl,utility);
					handler.parseHttpRequest(sb.toString(), out);
					out.close();
					break;
				}
				else if(fromClient.trim().toLowerCase().startsWith("remove"))
				{
					handler=new DeleteServerHandler(rwl,utility);
					System.out.println("I need to delete one server");
					handler.parseHttpRequest(sb.toString(), out);
					out.close();
					break;
				}
				else if(fromClient.trim().toLowerCase().startsWith("election"))
				{
					handler=new ElectionNoticeHandler(rwl,utility);
					System.out.println("************************start election*********************");
					handler.parseHttpRequest(sb.toString(), out);
					out.close();
					break;
				}
				

			}
			in.close();
			clientSocket.close();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		
		

		
	}
	
	
}
